extends Node2D

@onready var score_ui = %ScoreUi
@onready var rank_ui_start: VBoxContainer = $StartUi/RankUi
@onready var rank_ui_game_over: VBoxContainer = $GameOver/VBoxContainer/RankUi
@onready var start_ui = $StartUi

var spawn_rock_timer:Timer = Timer.new()
var max_spawn_rock_time:float = 1.5
var min_spawn_rock_time:float = 1.0
var has_rock_timer:bool = false
const STAR = preload("res://scenes/star.tscn")
const ROCK = preload("res://scenes/rock.tscn")
const RANK_LIST = preload("res://scenes/rank_list.tscn")
var plane:CharacterBody2D = null
var rock_position_x:float = 864.0
var max_rock_y:float = 368.0 # 石头在下方时最大Y轴位置
var min_rock_y:float = 496.0 # 石头在下方时最小Y轴位置
var max_rock_y_rotate:float = 104.0 # 石头在上方时最大Y轴位置
var min_rock_y_rotate:float = -8.0 # 石头在上方时最小Y轴位置
var use_time_timer:Timer = Timer.new()
var use_time:int = 0 #游戏时间
var is_stop_spawn_rock: bool = true #是否停止生成岩石
var max_spwan_star_time: int = 15 # 星星生成的最大时间
var min_spwan_star_time: int = 5 # 星星生成的最小时间
var star_position_x:float = 850.0 #星星生成的x轴位置
var max_star_y:float = 400.0 # 星星生成的最大Y轴位置
var min_star_y:float = 40.0 # 星星生成的最小Y轴位置
var spawn_star_timer:Timer = Timer.new()
var star_score = [50,20,10] # 拿取星星的分数，分别是金、银、铜
var star_counts = [0,0,0]  # 拿取星星的数量，分别是金、银、铜
var total_score:int = 0 #总分数，将时间与获取的星星转换成分数

# 加载数据，用于显示排行榜
func _ready():
	#print(Time.get_datetime_string_from_system())
	get_save_data()
	rank_ui_start.reflesh_data()
	pass

#获取保存的数据
func get_save_data():
	if not FileAccess.file_exists(Global.rank_data_url):
		print("not found file " + Global.rank_data_url)
		return
	var rank_data_file = FileAccess.open(Global.rank_data_url,FileAccess.READ)
	while  rank_data_file.get_position() < rank_data_file.get_length():
		var data_str = rank_data_file.get_line()
		Global.rank_data = translate_data_to_dict(data_str)
	rank_data_file.close()
	
# 保存数据到文件
func save_data():
	# 游戏时间小于1分钟的不记录
	if use_time < 30:
		return
	var new_data_dict:Dictionary = {
		"plane_type":Global.plane_type,
		"score":total_score,
		"star_counts":star_counts,
		"use_time":use_time,
		"time":Time.get_datetime_string_from_system()
	}
	Global.rank_data["players_score"].append(new_data_dict)
	# 排序后再写入数据
	Global.rank_data["players_score"].sort_custom(sort_data)
	print(Global.rank_data)
	var rank_data_file = FileAccess.open(Global.rank_data_url,FileAccess.WRITE)
	rank_data_file.store_line(JSON.stringify(Global.rank_data))
	rank_data_file.close()

func sort_data(a,b):
	if a["score"] > b["score"]:
		return true
	return false
	
# 获取文件的数据以字典形式返回：
func translate_data_to_dict(data_str)->Dictionary:
	print("translate:"+data_str)
	var json = JSON.new()
	var parse_result = json.parse(data_str)
	if parse_result  != OK:
		print("no json data")
		return {}
	return json.data

# 开始游戏，隐藏开始UI、隐藏分数UI、初始化飞机位置、生成石头
func start_game():
	init_game()
	$StartUi.hide()
	%ScoreUi.show()
	$ground.show()
	plane = load("res://scenes/plane.tscn").instantiate()
	get_tree().get_root().add_child(plane)
	plane.plane_outside.connect(_on_plane_outside)
	plane.position = Vector2(150,240)
	Global.bg_start_scroll = true
	add_child(use_time_timer)
	use_time_timer.timeout.connect(_on_use_timer_timeout)
	use_time_timer.wait_time = 1.0
	use_time_timer.start()
	is_stop_spawn_rock = false
	spawn_rock()
	spawn_star()
	$bgm.play()
	pass

# 生成石头	
func spawn_rock():
	if is_stop_spawn_rock:
		return
	if !has_rock_timer:
		spawn_rock_timer.timeout.connect(_on_rock_timer_timeout)
		spawn_rock_timer.wait_time = randf_range(min_spawn_rock_time,max_spawn_rock_time)
		add_child(spawn_rock_timer)
		spawn_rock_timer.start()
		has_rock_timer = true
	else:
		var rock = ROCK.instantiate()
		add_child(rock)
		rock.rock_entered.connect(_on_rock_entered)
		# 随机生成0或1，0--石头在下方，1--石头在上方
		if int(randi() % 2) == 0:
			var y =randf_range(min_rock_y,max_rock_y)
			rock.position = Vector2(rock_position_x,y)
		else:
			rock.rotation_degrees = 180
			rock.position = Vector2(rock_position_x,randf_range(min_rock_y_rotate,max_rock_y_rotate))
			
func spawn_star():
	if is_stop_spawn_rock:
		return

	spawn_star_timer.one_shot = true
	spawn_star_timer.timeout.connect(_on_star_timer_timeout)
	spawn_star_timer.wait_time = randf_range(min_spwan_star_time,max_spwan_star_time)
	add_child(spawn_star_timer)
	spawn_star_timer.start()

	var star = STAR.instantiate()
	add_child(star)
	star.star_entered.connect(_on_star_enter)
	# 随机生成0或1，0--石头在下方，1--石头在上方
	var y =randf_range(min_star_y,max_star_y)
	star.position = Vector2(star_position_x,y)

#初始化游戏，参数、节点位置等
func init_game():
	has_rock_timer = false
	spawn_rock_timer.stop()
	use_time = 0
	score_ui.update_score(use_time)
	total_score = 0
	star_counts = [0,0,0]
	spawn_star_timer.stop()
	pass

func game_over():
	print("game over")
	plane.queue_free()
	$GameOver/VBoxContainer/VBoxContainer/CenterContainer3/Label2.set_text("你的分数是："+str(total_score))
	%ScoreUi.hide()
	$GameOver.show()
	use_time_timer.stop()
	is_stop_spawn_rock = true
	var rock_group = get_tree().get_nodes_in_group("rock")
	for child in rock_group:
		child.queue_free()
	$bgm.stop()
	$FailAudio.play()
	save_data()
	rank_ui_game_over.reflesh_data()

func _on_star_timer_timeout():
	print("star timer timeout")
	spawn_star()
	pass

func _on_star_enter(index:int):
	print("start enter")
	star_counts[index] += 1
	total_score += star_score[index]
	score_ui.update_stars_count(star_counts)

func _on_plane_outside():
	game_over()
	
func _on_rock_entered():
	game_over()
	pass

func _on_rock_timer_timeout():
	spawn_rock()
	pass
	
func _on_use_timer_timeout():
	use_time += 1
	total_score += 1 
	score_ui.update_score(total_score)
	pass

func _on_blue_button_pressed():
	Global.plane_type = Global.PLANE_TYPE.BULE_PLANE
	#$ClickAudio.play()
	pass # Replace with function body.


func _on_green_button_pressed():
	Global.plane_type = Global.PLANE_TYPE.GREEN_PLANE
	#$ClickAudio.play()
	pass # Replace with function body.


func _on_red_button_pressed():
	Global.plane_type = Global.PLANE_TYPE.RED_PLANE
	#$ClickAudio.play()
	pass # Replace with function body.


func _on_yellow_button_pressed():
	Global.plane_type = Global.PLANE_TYPE.YELLOW_PLANE
	#$ClickAudio.play()
	pass # Replace with function body.


func _on_start_button_pressed():
	start_game()
	pass # Replace with function body.



func _on_restart_button_pressed():
	$GameOver.hide()
	$StartUi.show()
	$ground.hide()
	rank_ui_start.reflesh_data()
	pass # Replace with function body.


func _on_end_button_pressed():
	get_tree().quit()
	pass # Replace with function body.


func _on_rank_button_pressed():
	var rank_list_ui = RANK_LIST.instantiate()
	add_child(rank_list_ui)
	rank_list_ui.size = Vector2(608,464)
	rank_list_ui.position = Vector2(96,20)
	pass # Replace with function body.
